package com.atzly.community.controller;

import com.atzly.community.annotation.LoginRequired;
import com.atzly.community.constant.CommentConstant;
import com.atzly.community.entity.*;
import com.atzly.community.service.*;
import com.atzly.community.utils.CommunityUtils;
import com.atzly.community.utils.HostHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * 用户相关业务
 * 1 用户修改照片
 * 2 用户修改密码
 *
 * @author zlysimida
 * @date 2021/8/27 - 14:43
 */
@Controller
@RequestMapping("/user")
@Slf4j
public class UserController implements CommentConstant {

    @Value("${community.path.domin}")
    private String domin;

    @Value("${server.servlet.context-path}")
    private String contentPath;

    @Value("${community.path.upload}")
    private String uploadPath;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private UserService userService;

//    @Autowired
//    private LoginTicketService loginTicketService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private FollowService followService;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private CommentService commentService;

    @LoginRequired
    @GetMapping("/setting")
    public String settingPage() {
        return "/site/setting";
    }

    // 实现上传功能
    @LoginRequired
    @PostMapping("/upload")
    public String uploadHeader(MultipartFile headImage, Model model) {
        if (headImage == null) {
            model.addAttribute("error", " 您还没有选择图片!");
            return "/site/setting";
        }

        // 获得上传的图片信息
        String filename = headImage.getOriginalFilename();
        String suffix = Objects.requireNonNull(filename).substring(filename.lastIndexOf("."));
        if (StringUtils.isBlank(suffix)) {
            model.addAttribute("error", "文件格式不正确");
            return "/site/setting";
        }

        // 生成随机文件名
        filename = CommunityUtils.randomString() + filename;
        // 保存的文件路径
        File dest = new File(uploadPath + "/" + filename);
        try {
            // 保存图片
            headImage.transferTo(dest);
        } catch (IOException e) {
            log.error("文件上传失败!" + e.getMessage());
            throw new RuntimeException("上传文件失败,服务器发送异常!", e);
        }

        // 更新数据库表中的用户头像路径
        // http://localhost:8080/community/user/header/xxx.png
        User user = hostHolder.getUserFromThread();
        String headerUrl = domin + contentPath + "/user/header/" + filename;
        userService.updateHeader(user.getId(), headerUrl);

        return "redirect:/index";
    }

    // 服务器响应更新的头像
    // http://localhost:8080/community/user/header/xxx.png
    @GetMapping("/header/{filename}")
    public void getHeader(@PathVariable("filename") String filename,
                          HttpServletResponse response) {
        // 服务器存放的路径
        filename = uploadPath + "/" + filename;
        // 获取后缀名(为了响应文件的格式),读取图片并响应
        String suffix = filename.substring(filename.lastIndexOf("."));
        response.setContentType("image/" + suffix);
        try (
                FileInputStream fis = new FileInputStream(filename);
                OutputStream os = response.getOutputStream();
        ) {
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } catch (Exception e) {
            log.error("读取头像失败!" + e.getMessage());
        }
    }

    // 修改密码
    @LoginRequired
    @Transactional
    @PostMapping("/setting")
    public String resetUserPwd(String newPwd, String oldPwd, Model model, @CookieValue("ticket") String ticket) {
        User user = hostHolder.getUserFromThread();
        oldPwd = CommunityUtils.md5(oldPwd + user.getSalt());
        if (!Objects.equals(oldPwd, user.getPassword())) {
            model.addAttribute("oldPwdErr", "您输入的旧密码有误!");
            return "/site/setting";
        }
        if (newPwd == null) {
            model.addAttribute("pwdErr", "您输入的密码不能为空!");
            return "/site/setting";
        }

        // 修改数据库user表和ticket表数据
        newPwd = CommunityUtils.md5(newPwd + user.getSalt());
        userService.updatePassword(user.getId(), newPwd);

        //loginTicketService.updateTicketStatus(ticket,1);
        // redis重构
        userService.logout(ticket);
        hostHolder.removeUserFromThread();
        return "redirect:/login";
    }

    // 个人主页查询
    @GetMapping("/profile/{userId}")
    public String profile(@PathVariable("userId") int userId, Model model) {
        User user = userService.selectById(userId);
        if (user == null) {
            throw new RuntimeException("改用户不存在!");
        }

        // 用户
        model.addAttribute("user", user);
        // 点赞数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount", likeCount);
        // 查询已关注数量(用户)
        long followeeCount = followService.followeeCount(userId, CommentConstant.ENTITY_TYPE_USER);
        model.addAttribute("followeeCount", followeeCount);
        // 查询粉丝数量
        long followerCount = followService.followerCount(CommentConstant.ENTITY_TYPE_USER, userId);
        model.addAttribute("followerCount", followerCount);
        // 查询是否关注了其他人
        boolean hasFollowed = false;
        if (hostHolder.getUserFromThread() != null) {
            hasFollowed = followService.hasFollowed(hostHolder.getUserFromThread().getId(), CommentConstant.ENTITY_TYPE_USER, userId);
        }
        model.addAttribute("hasFollowed", hasFollowed);
        return "/site/profile";
    }

    // 返回帖子的标题，帖子内容，创建时间，点赞数量，用户id，帖子总数
    @GetMapping("/mypost/{userId}")
    public String myPost(@PathVariable("userId") int userId, Page page, Model model) {
        User user = userService.selectById(userId);
        if (user == null) {
            throw new IllegalArgumentException("当前查询user不存在!!!");
        }
        model.addAttribute("user", user);
        page.setPath("/user/mypost/" + userId);
        // 查询全部数量
        Integer postNum = discussPostService.selectDiscussByUserId(userId);
        page.setTotal(postNum);
        page.setLimit(5);
        List<DiscussPost> postList = discussPostService.selectDiscussPost(userId, page.getOffset(), page.getLimit(), 1);
        List<Map<String, Object>> postVo = new ArrayList<>();
        if (postList != null) {
            for (DiscussPost post : postList) {
                Map<String, Object> vo = new HashMap<>();
                vo.put("discussId", post.getId());
                vo.put("title", post.getTitle());
                vo.put("content", post.getContent());
                vo.put("createTime", post.getCreateTime());
                vo.put("like", likeService.findEntityLikeCount(CommentConstant.ENTITY_TYPE_POST, post.getId()));
                postVo.add(vo);
            }
        }
        model.addAttribute("postNums", postNum);
        model.addAttribute("postVo", postVo);
        return "/site/my-post";
    }

    // 返回我的回复数量,帖子标题,回复内容,回复时间
    // 获取对帖子的评论
    @GetMapping("/myreply/{userId}")
    public String myReple(@PathVariable("userId") int userId, Page page, Model model) {
        User user = userService.selectById(userId);
        if (user == null) {
            throw new IllegalArgumentException("当前查询user不存在!!!");
        }
        page.setPath("/user/myreply/" + userId);
        page.setLimit(5);
        model.addAttribute("user", user);
        // 查询我直接对帖子的评论以及我对评论的评论
        Integer commentNums = commentService.getCommentNumsByUserId(userId, CommentConstant.ENTITY_TYPE_POST, CommentConstant.ENTITY_TYPE_COMMENT);
        page.setTotal(commentNums);
        model.addAttribute("commentNums", commentNums);
        // 封装结果集
        List<Map<String, Object>> commentVo = new ArrayList<>();
        List<Comment> commentList = commentService.getCommentByUserPage(userId, CommentConstant.ENTITY_TYPE_POST, CommentConstant.ENTITY_TYPE_COMMENT, page.getOffset(), page.getLimit());
        if (commentList != null) {
            for (Comment comment : commentList) {
                Map<String, Object> vo = new HashMap<>();
                vo.put("content", comment.getContent());
                vo.put("createTime", comment.getCreateTime());
//                // 获取被评论的标题
//                // 这里一直查询数据库可以优化数据库表结构
                while (comment.getEntityType() != CommentConstant.ENTITY_TYPE_POST) {
                    comment = commentService.selectCommuntById(comment.getEntityId());
                }
                DiscussPost post = discussPostService.selectDiscussDetails(comment.getEntityId());
                String title = post.getTitle();
                vo.put("discussId", post.getId());
                vo.put("title", title);
                commentVo.add(vo);
            }
        }
        model.addAttribute("commentVo", commentVo);
        return "/site/my-reply";
    }


    @GetMapping("/denied")
    public String denied() {
        return "/error/404";
    }
}
